package org.dalmatian.common.core.utils;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.dalmatian.common.core.exception.ServiceException;

/**
 * 校验业务类
 *
 * @author wbw_0
 */
public class ValidateBiz {

    private ValidateBiz() {
    }

    public static <R> R isNull(R obj, int c, String s) {
        if (obj == null) {
            throw new ServiceException(s, c);
        }
        return obj;
    }

    public static <T, R> R isNull(Function<T, R> func, T t, int c, String s) {
        R result = func.apply(t);
        if (result == null) {
            throw new ServiceException(s, c);
        }
        return result;
    }

    public static <T, R> R isNull(Function<T, R> func, T t, Predicate<R> predicate, String s) {
        R result = func.apply(t);
        if (result == null || predicate.test(result)) {
            throw new ServiceException(s);
        }
        return result;
    }

    public static <T, R> R isNull(Function<T, R> func, T t, Predicate<R> predicate, int c,
        String s) {
        R result = func.apply(t);
        if (result == null || predicate.test(result)) {
            throw new ServiceException(s, c);
        }
        return result;
    }

    /**
     * 是否 null
     *
     * @param func      执行方法
     * @param t         参数
     * @param predicate 断言
     * @param res       返回处理
     */
    public static <T, R, V> V isNull(
        Function<T, R> func, T t, Predicate<R> predicate, Function<R, V> res, int c, String s) {
        R result = func.apply(t);
        if (result == null || predicate.test(result)) {
            throw new ServiceException(s, c);
        }
        return res.apply(result);
    }

    public static <R> R isNull(R obj, String s) {
        if (obj == null) {
            throw new ServiceException(s);
        }
        return obj;
    }

    public static <R> List<R> isNull(int c, String s, R... obj) {
        for (Object o : obj) {
            if (o == null) {
                throw new ServiceException(s, c);
            }
        }
        return Arrays.stream(obj).collect(Collectors.toList());
    }

    public static <T, R> R isNull(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (result == null) {
            throw new ServiceException(s);
        }
        return result;
    }

    public static <R> List<R> isNull(String s, R... obj) {
        for (Object o : obj) {
            if (o == null) {
                throw new ServiceException(s);
            }
        }
        return Arrays.stream(obj).collect(Collectors.toList());
    }

    public static <R> R isNotNull(R o, int c, String s) {
        if (ObjectUtil.isNotNull(o)) {
            throw new ServiceException(s, c);
        }
        return o;
    }

    public static <T, R> R isNotNull(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (ObjectUtil.isNotNull(result)) {
            throw new ServiceException(s);
        }
        return result;
    }

    public static <T, R> R isNotNull(Function<T, R> func, T t, int c, String s) {
        R result = func.apply(t);
        if (ObjectUtil.isNotNull(result)) {
            throw new ServiceException(s, c);
        }
        return result;
    }

    public static <R> R isNotNull(R o, String s) {
        if (ObjectUtil.isNotNull(o)) {
            throw new ServiceException(s);
        }
        return o;
    }

    public static <R> R isEmpty(R obj, int c, String s) {
        if (ObjectUtil.isEmpty(obj)) {
            throw new ServiceException(s, c);
        }
        return obj;
    }

    public static <T, R> R isEmpty(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (ObjectUtil.isEmpty(result)) {
            throw new ServiceException(s);
        }
        return result;
    }

    public static <R> List<R> isEmpty(String s, R... obj) {
        for (R o : obj) {
            if (ObjectUtil.isEmpty(o)) {
                throw new ServiceException(s);
            }
        }
        return Arrays.stream(obj).collect(Collectors.toList());
    }

    public static <R> R isEmpty(R r, String s) {
        if (ObjectUtil.isEmpty(r)) {
            throw new ServiceException(s);
        }
        return r;
    }

    public static Number isEmpty(Number r, String s) {
        if (r == null || r.doubleValue() == 0.0 || r.longValue() == 0) {
            throw new ServiceException(s);
        }
        return r;
    }

    public static <R> R isNotEmpty(R r, String s) {
        if (ObjectUtil.isNotEmpty(r)) {
            throw new ServiceException(s);
        }
        return r;
    }

    public static <R> R isNotEmpty(R obj, int c, String s) {
        if (ObjectUtil.isNotEmpty(obj)) {
            throw new ServiceException(s, c);
        }
        return obj;
    }

    public static <R extends CharSequence> R isBlank(R r, String s) {
        if (CharSequenceUtil.isBlank(r)) {
            throw new ServiceException(s);
        }
        return r;
    }

    public static void isFalse(boolean flag, String s) {
        if (!flag) {
            throw new ServiceException(s);
        }
    }

    public static void isFalse(boolean flag, int c, String s) {
        if (!flag) {
            throw new ServiceException(s, c);
        }
    }

    public static void isFalse(Supplier<Boolean> func, int c, String s) {
        if (!func.get()) {
            throw new ServiceException(s, c);
        }
    }

    public static <T> void isFalse(Function<T, Boolean> func, T t, int c, String s) {
        if (!func.apply(t)) {
            throw new ServiceException(s, c);
        }
    }

    public static <T> void isFalse(Function<T, Boolean> func, T t, String s) {
        if (!func.apply(t)) {
            throw new ServiceException(s);
        }
    }

    public static void isTrue(boolean flag, String s) {
        if (flag) {
            throw new ServiceException(s);
        }
    }

    public static void isTrue(boolean flag, int c, String s) {
        if (flag) {
            throw new ServiceException(s, c);
        }
    }

    public static <T, R extends Boolean> T isTrue(Function<T, R> func, T t, String s) {
        R flag = func.apply(t);
        if (flag.booleanValue()) {
            throw new ServiceException(s);
        }
        return t;
    }

    /**
     * 负数
     */
    public static <R extends Number> R isMinus(R num, String s) {
        if (num.longValue() < 0) {
            throw new ServiceException(s);
        }
        return num;
    }

    public static <T, R extends Number> R requiredNotEmptyNum(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (result.longValue() != 0 || result.doubleValue() != 0.0) {
            return result;
        }
        throw new ServiceException(s);
    }

    public static <T, R extends Number> R isNotEmptyNum(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (result.longValue() != 0 || result.doubleValue() != 0.0) {
            throw new ServiceException(s);
        }
        return result;
    }

    public static <T, R extends Number> R isEmptyNum(Function<T, R> func, T t, String s) {
        R result = func.apply(t);
        if (result.longValue() == 0 || result.doubleValue() == 0.0) {
            return result;
        }
        throw new ServiceException(s);
    }

    public static <T> T isException(Consumer<T> consumer, T t, String s) {
        try {
            consumer.accept(t);
        } catch (Exception e) {
            throw new ServiceException(s);
        }
        return t;
    }

    public static void error(String s) {
        throw new ServiceException(s);
    }

    /**
     * 是否存在
     *
     * @param func 任务
     * @param t    参数
     * @param s    信息
     */
    public static <T> void isExist(Function<T, Integer> func, T t, String s) {
        Integer count = func.apply(t);
        if (count > 0) {
            throw new ServiceException(s);
        }
    }

    public static int isExist(IntSupplier supplier, String s) {
        int count = supplier.getAsInt();
        if (count > 0) {
            throw new ServiceException(s);
        }
        return count;
    }

    public static int isExist(int count, String s) {
        if (count > 0) {
            throw new ServiceException(s);
        }
        return count;
    }

    /**
     * 存在多个
     *
     * @param func 任务
     * @param t    参数
     * @param s    信息
     */
    public static <T> int isMulti(Function<T, Integer> func, T t, String s) {
        int count = func.apply(t);
        if (count > 1) {
            throw new ServiceException(s);
        }
        return count;
    }

    public static int isMulti(int count, String s) {
        if (count > 1) {
            throw new ServiceException(s);
        }
        return count;
    }

    public static void isEquals(Object obj1, Object obj2, String s) {
        if (ObjectUtil.equals(obj1, obj2)) {
            throw new ServiceException(s);
        }
    }

    public static void isNotEquals(Object obj1, Object obj2, String s) {
        if (!ObjectUtil.equals(obj1, obj2)) {
            throw new ServiceException(s);
        }
    }

    public static void exception(String s) {
        throw new ServiceException(s);
    }

    public static void isNotIn(String msg, String val, String... params) {
        for (String param : params) {
            if (CharSequenceUtil.equals(val, param)) {
                return;
            }
        }
        throw new ServiceException(msg);
    }

    public static void hasBlank(String msg, String... params) {
        if (CharSequenceUtil.hasBlank(params)) {
            throw new ServiceException(msg);
        }
    }
}
